# -*- coding: utf-8 -*-

import json
import logging

from common.admin import db as user_db
from common.bankcard.db import get_bankcard_name_by_account_number
from common.mch import db as mch_db
from common.order_withdraw import db as order_withdraw_db
from common.order_withdraw import handler as order_withdraw_handler
from common.order_withdraw.db import ORDER_STATUS
from common.utils.api import check_params
from common.utils.api import token_required
from common.utils.decorator import response_wrapper
from common.utils.tz import (
    utc_to_local_str
)
from django.utils.decorators import method_decorator
from django.utils.encoding import smart_unicode
from django.views.generic import TemplateView

_LOGGER = logging.getLogger('hydra')


class OrderWithdrawView(TemplateView):
    def get(self, req):
        query_dct = req.GET.dict()
        order_type = req.GET.dict()['order_type']
        from admin.views import add_query_fliter
        add_query_fliter(req, query_dct)
        _LOGGER.info('OrderWithdrawView get orders: %s, ', query_dct)

        items, total_count = order_withdraw_db.list_order(query_dct, order_type)
        mch_names = mch_db.get_mch_name_dict()
        resp_items = []
        for item in items:
            data = item.as_dict()
            data['id'] = str(data['id'])
            data['mch_id'] = mch_names[data['mch_id']]
            data['created_at'] = utc_to_local_str(data['created_at'])
            data['updated_at'] = utc_to_local_str(data['updated_at'])
            data['operating_time'] = utc_to_local_str(data['operating_time']) if data['operating_time'] else ''
            data['exact_time'] = utc_to_local_str(data['exact_time']) if data['exact_time'] else ''
            data['reassign_time'] = utc_to_local_str(data['reassign_time']) if data['reassign_time'] else ''
            data['exact_amount'] = 0.00
            data['destination_card_code'] = get_bankcard_name_by_account_number(data['account_number'])
            if data['status'] not in [ORDER_STATUS.PENDING, ORDER_STATUS.PROCESSING, ORDER_STATUS.INVALID]:
                data['exact_amount'] = data['amount']
            data['selected'] = False
            resp_items.append(data)
        _LOGGER.info('total_count: %s, ', total_count)
        exact_amount, amount, success_rate = order_withdraw_db.get_order_overview(query_dct, order_type)
        calc_succ_rate = float(total_count) + 0.00
        if success_rate != 0 and calc_succ_rate != 0:
            calc_succ_rate = success_rate / calc_succ_rate
        else:
            calc_succ_rate = 0
        return {'list': resp_items, 'page': query_dct.get('$page', 1),
                'size': len(resp_items), 'total_count': total_count, 'exact_amount': exact_amount,
                'amount': amount, 'success_rate': calc_succ_rate * 100}

    @method_decorator(response_wrapper)
    @method_decorator(token_required)
    def dispatch(self, *args, **kwargs):
        return super(OrderWithdrawView, self).dispatch(*args, **kwargs)


class SingleOrderWithdrawView(TemplateView):
    def post(self, req, order_id):
        _LOGGER.info('edit order withdraw: %s', req.body)
        params = json.loads(smart_unicode(req.body))

        user = user_db.get_user(int(req.user_id))
        if not user:
            raise err.ResourceNotFound('req.user_id {} not found'.format(req.user_id))

        params['updated_by'] = user.nickname
        check_params(params, ['order_id', 'status', 'notes', 'operating_time'])

        order_id = params['order_id']
        if order_withdraw_handler.check_valid_order(params, order_withdraw_handler.order_withdraw_finished):
            order = order_withdraw_db.edit_order(params)
            order_withdraw_handler.notify({'order_id': order_id})

        _LOGGER.info('edit order_id: %s', order_id)
        return {'result': 'ok', 'id': order_id}

    def put(self, req, order_id):
        _LOGGER.info('push order withdraw: %s', req.body)
        params = json.loads(smart_unicode(req.body))
        user = user_db.get_user(int(req.user_id))
        if not user:
            raise err.ResourceNotFound('req.user_id {} not found'.format(req.user_id))

        params['updated_by'] = user.nickname
        check_params(params, ['order_id'])
        order_id = params['order_id']
        status_msg = 'order_id {} is still'.format(order_id)
        if order_withdraw_handler.check_valid_order(params, order_withdraw_handler.order_withdraw_not_finished,
                                                    status_msg):
            order_withdraw_handler.notify(params)

        _LOGGER.info('push order_id: %s', order_id)
        return {'result': 'ok', 'id': order_id}

    @method_decorator(response_wrapper)
    @method_decorator(token_required)
    def dispatch(self, *args, **kwargs):
        return super(SingleOrderWithdrawView, self).dispatch(*args, **kwargs)
